@@ -27,4 +27,20 @@ module LiquidDroppable |
||
| 27 | 27 |
def to_liquid |
| 28 | 28 |
self.class::Drop.new(self) |
| 29 | 29 |
end |
| 30 |
+ |
|
| 31 |
+ require 'uri' |
|
| 32 |
+ |
|
| 33 |
+ class URIDrop < Drop |
|
| 34 |
+ URI::Generic::COMPONENT.each { |attr|
|
|
| 35 |
+ define_method(attr) {
|
|
| 36 |
+ @object.__send__(attr) |
|
| 37 |
+ } |
|
| 38 |
+ } |
|
| 39 |
+ end |
|
| 40 |
+ |
|
| 41 |
+ class ::URI::Generic |
|
| 42 |
+ def to_liquid |
|
| 43 |
+ URIDrop.new(self) |
|
| 44 |
+ end |
|
| 45 |
+ end |
|
| 30 | 46 |
end |
@@ -116,6 +116,22 @@ module LiquidInterpolatable |
||
| 116 | 116 |
CGI.escape(string) rescue string |
| 117 | 117 |
end |
| 118 | 118 |
|
| 119 |
+ # Parse an input into a URI object, optionally resolving it |
|
| 120 |
+ # against a base URI if given. |
|
| 121 |
+ # |
|
| 122 |
+ # A URI object will have the following properties: scheme, |
|
| 123 |
+ # userinfo, host, port, registry, path, opaque, query, and |
|
| 124 |
+ # fragment. |
|
| 125 |
+ def to_uri(uri, base_uri = nil) |
|
| 126 |
+ if base_uri |
|
| 127 |
+ URI(base_uri) + uri.to_s |
|
| 128 |
+ else |
|
| 129 |
+ URI(uri.to_s) |
|
| 130 |
+ end |
|
| 131 |
+ rescue URI::Error |
|
| 132 |
+ nil |
|
| 133 |
+ end |
|
| 134 |
+ |
|
| 119 | 135 |
# Escape a string for use in XPath expression |
| 120 | 136 |
def to_xpath(string) |
| 121 | 137 |
subs = string.to_s.scan(/\G(?:\A\z|[^"]+|[^']+)/).map { |x|
|
@@ -59,4 +59,41 @@ describe LiquidInterpolatable::Filters do |
||
| 59 | 59 |
@filter.to_xpath_roundtrip(1).should == '1' |
| 60 | 60 |
end |
| 61 | 61 |
end |
| 62 |
+ |
|
| 63 |
+ describe 'to_uri' do |
|
| 64 |
+ before do |
|
| 65 |
+ @agent = Agents::InterpolatableAgent.new(name: "test", options: { 'foo' => '{% assign u = s | to_uri %}{{ u.path }}' })
|
|
| 66 |
+ @agent.interpolation_context['s'] = 'http://example.com/dir/1?q=test' |
|
| 67 |
+ end |
|
| 68 |
+ |
|
| 69 |
+ it 'should parse an abosule URI' do |
|
| 70 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
|
|
| 71 |
+ end |
|
| 72 |
+ |
|
| 73 |
+ it 'should parse an abosule URI with a base URI specified' do |
|
| 74 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
|
|
| 75 |
+ end |
|
| 76 |
+ |
|
| 77 |
+ it 'should parse a relative URI with a base URI specified' do |
|
| 78 |
+ @filter.to_uri('foo/index.html', 'http://example.com/dir/1').should == URI('http://example.com/dir/foo/index.html')
|
|
| 79 |
+ end |
|
| 80 |
+ |
|
| 81 |
+ it 'should parse an abosule URI with a base URI specified' do |
|
| 82 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html')
|
|
| 83 |
+ end |
|
| 84 |
+ |
|
| 85 |
+ it 'should stringify a non-string operand' do |
|
| 86 |
+ @filter.to_uri(123, 'http://example.com/dir/1').should == URI('http://example.com/dir/123')
|
|
| 87 |
+ end |
|
| 88 |
+ |
|
| 89 |
+ it 'should return a URI value in interpolation' do |
|
| 90 |
+ @agent.interpolated['foo'].should == '/dir/1' |
|
| 91 |
+ end |
|
| 92 |
+ |
|
| 93 |
+ it 'should return a URI value resolved against a base URI in interpolation' do |
|
| 94 |
+ @agent.options['foo'] = '{% assign u = s | to_uri:"http://example.com/dir/1" %}{{ u.path }}'
|
|
| 95 |
+ @agent.interpolation_context['s'] = 'foo/index.html' |
|
| 96 |
+ @agent.interpolated['foo'].should == '/dir/foo/index.html' |
|
| 97 |
+ end |
|
| 98 |
+ end |
|
| 62 | 99 |
end |